# -*- coding: utf-8 -*-

#    OriginDB
#    Copyright (C) 2010  Brian Plattenburg <alphastryk@gmail.com>
#    Copyright (C) 2010  Travis Gockel <travis@gockelhut.com>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import unittest
import sys
import yaml

sys.path.append('../')

from reaction import Reaction
from testCommon import *
import reactionData

class ReactionTest (unittest.TestCase):
	pass
	#def setUp(self):
		#setupDB();
		
	#def teardown(self):
		#pass;
	
	#def testInsert (self):
		#react = Reaction(reaction1)
		#react.insert()
		#return

	#def testUpdate (self):
		#react = Reaction(reaction1)
		#react.insert()
		#react.forceUpdate()
		#return

	#def testLoad (self):
		#react = Reaction(reaction1)
		#react.insert()
		#react.load()
		#return

	#def testLoadValidData(self):
		#react = Reaction(reaction1)
		#react.insert()
		#react2 = Reaction.load(react)
		#self.assertEqual(react, react2)
		#return
	
class ReactionYamlTest (unittest.TestCase):
	
	def testLoadStringYaml(self):
		for i in range(len(reactionData.reactionYamls)):
			yml = reactionData.reactionYamls[i]
			react = Reaction()
			react._loadYAML(yml)
			goodYaml = yaml.load(yml)
			
			# check single attributes
			self.assertEqual(react.temperature, goodYaml['temperature'])
			self.assertEqual(react.liquid, goodYaml['liquid'])
			self.assertEqual(react.reference.key, goodYaml['reference'])
			
			# check catalyst list by key
			goodCatalysts = goodYaml['catalysts']
			catalystSet = set()
			for catalyst in react.catalysts:
				catalystSet.add(catalyst.key)
			goodCatalystSet = set(goodYaml['catalysts'])
			self.assertEqual(catalystSet, goodCatalystSet)
			
			#check product list by key and percent
			goodProducts = goodYaml['products']
			productSet = set(react.products)
			goodProdSet = set()
			for product in goodProducts:
				goodProdSet.add ( str(product) + ":" + str(goodProducts[product]) )
			formattedProdSet = set()
			for product in productSet:
				formattedProdSet.add( str(product.key) + ":" + str(product._things['percent']) )
			self.assertEqual(formattedProdSet, goodProdSet)
		return
		
	def testDumpYaml(self):
		for i in range(len(reactionData.reactionYamls)):
			yml = reactionData.reactionYamls[i]
			react = Reaction()
			react._loadYAML(yml)
			reactDump = react._dumpYAML()
			goodDump = yaml.dump(react._things)
			self.assertEqual(reactDump, goodDump)
			# This may not be a valid test, as list ordering for reactants, reactions, and products is not static or gaurunteed.
		return
	
class ReactionDBTest (unittest.TestCase):
	
	def setUp(self):
		setupDB()
		from referenceData import references
		from compoundData import compoundYamls
		self.compoundKeys = []
		for i in range(20,2):
			resp = dbHandle.postAction("insert", compoundYamls[i], {'type':"Compound"})
			data = yaml.load(resp)
			self.compoundKeys.append(data['key'])
		referenceKeys = []
		for i in range(6,2):
			resp = dbHandle.postAction("insert", references[i], {'type':"Compound"})
			data = yaml.load(resp)
			self.referenceKeys.append(data['key'])
		
			
		self.keys = []
		self.catalystKeys = []
		
		return

	def testInsertGetCatalysts(self):
		for i in reactionData.catalystYamls:
			resp = dbHandle.postAction("insert", i, {'type':"Catalyst"})
			d = yaml.load(resp)
			self.assert_("key" in d.keys())
			self.catalystKeys.append(d["key"])
			resp = dbHandle.getAction("get", {'type':"Catalyst", 'key':d['key']})
			dataGot = yaml.load(resp)
			data = yaml.load(i)
			for key in data:
				self.assertEqual(data[key], dataGot[key], "for %s had %s got %s" % (key, data[key], dataGot[key]))

	def testInsertGet(self):

		self.testInsertGetCatalysts()
		
		data = yaml.load(reactionData.reactionYamls)
		self.reaction1 = data[0]
		self.reaction1.reactants = {}
		self.reaction1.products = {}
		self.reaction1.catalysts = []
		self.reaction1.reactants[compoundKeys[0]] = 12
		self.reaction1.reactants[compoundKeys[1]] = 13
		self.reaction1.products[compoundKeys[3]] = 14
		self.reaction1.products[compoundKeys[4]] = 15
		self.reaction1.products[compoundKeys[5]] = 16
		self.reaction1.reference = referenceKeys[0]
		self.reaction1.catalysts.append(catalystKeys[0])
		self.reaction1.catalysts.append(catalystKeys[1])
		self.reaction2 = data[1]
		self.reaction2.reactants = {}
		self.reaction2.products = {}
		self.reaction2.catalysts = []
		self.reaction2.reactants[compoundKeys[6]] = 17
		self.reaction2.reactants[compoundKeys[7]] = 70
		self.reaction2.reactants[compoundKeys[8]] = 3
		self.reaction2.products[compoundKeys[9]] = 6
		self.reaction2.products[compoundKeys[0]] = 65
		self.reaction2.reference = referenceKeys[1]
		self.reaction2.catalysts.append(catalystKeys[2])
		self.reaction2.catalysts.append(catalystKeys[3])
		
		
		#for i in [yaml.dump(self.reaction1), yaml.dump(self.reaction2)]:
			#resp = dbHandle.postAction("insert", i, {'type':"Reaction"})
			#d = yaml.load(resp)
			#self.assert_("key" in d.keys())
			#self.keys.append(d['key'])
			#resp = dbHandle.getAction("get", {'type':"Reaction", 'key':d['key']})
			#dataGot = yaml.load(resp)
			#data = yaml.load(i)
			#for key in data:
				#self.assertEqual(data[key], dataGot[key], "for %s had %s got %s" % (key, data[key], dataGot[key]))

	def testSearch(self):
		print "Not Implemented"
		return

	def tearDown(self):
		clearDB()
		return

	#def testUpdateIssue(self):
		#for i in self.keys:
			#body = yaml.dump({"temperature":42})
			#dbHandle.postAction("update", body, {'type':'Reaction', 'key':i})
		#for i in keys:
			#resp = dbHandle.getAction("get", {'type':"Reaction", 'key':i})
			#dataGot = yaml.load(resp)
			#self.assertEqual(dataGot['temperature'], 42)

if __name__ == "__main__":
	unittest.main()   